#include "mysql.hpp"
#include "relation.hxx"
#include "relation-odb.hxx"

namespace xchat
{


class RelationTable
{
public:
    using ptr = std::shared_ptr<RelationTable>;

    RelationTable(const std::shared_ptr<odb::core::database>& db) 
        : _db(db) {}

    //新增用户关系
    bool insert(const std::string &uid, const std::string &pid)
    {
        //add(1, 2) (2, 1) 所以不传入对象
        try
        {
            Relation r1(uid, pid);
            Relation r2(pid, uid);
            odb::transaction trans(_db->begin());
            _db->persist(r1);
            _db->persist(r2);
            //提交事务
            trans.commit();
        }catch(std::exception &e){
            LOG_ERROR("新增Relation失败 {}-{} : {}",uid, pid, e.what());
            return false;
        }
        return true;
    }
    //移除用户关系
    bool remove(const std::string &uid, const std::string &pid)
    {
        try
        {
            odb::transaction trans(_db->begin());
            typedef odb::query<Relation> query;
            typedef odb::result<Relation> result;
            //似乎查找不到而删除 会报错？ TODO
            _db->erase_query<Relation>(query::user_id == uid && query::peer_id == pid); 
            _db->erase_query<Relation>(query::user_id == pid && query::peer_id == uid);

            trans.commit();
        }
        catch(std::exception &e){
            LOG_ERROR("删除Relation失败 {}-{} : {}",uid, pid, e.what());
            return false;
        }
        return true;
    }
    //判度关系是否存在
    bool exists(const std::string &uid, const std::string &pid)
    {
        typedef odb::query<Relation> query;
        typedef odb::result<Relation> result;
        std::shared_ptr<Relation> r;
        try
        {
            //开启事务
            odb::transaction trans(_db->begin());
            r = std::shared_ptr<Relation>(_db->query_one<Relation>(query::user_id == uid && query::peer_id == pid)); 
            //LOG_DEBUG("查询完毕");
            //提交事务
            trans.commit();

        }catch(std::exception &e){
            LOG_ERROR("查找Relation失败 {}-{} : {}",uid, pid, e.what());
        }
        return r != nullptr;
    }
    //获取指定用户的所有好友ID
    std::vector<std::string> friends(const std::string &uid)
    {
        std::vector<std::string> res;
        try
        {
            //开启事务
            odb::transaction trans(_db->begin());
            typedef odb::query<Relation> query;
            typedef odb::result<Relation> result;
            result r(_db->query<Relation>(query::user_id == uid));
            for (const auto &it : r)
            {
                res.push_back(it.peer_id());
            }
            //提交事务
            trans.commit();

        }catch(std::exception &e){
            LOG_ERROR("通过用户id列表查询其好友关系失败 {}", e.what());
        }
        return res;
    }
private:
    std::shared_ptr<odb::core::database> _db;
};

}